﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Collections;
//MicroDesigner
using Jc.MicroDesigner.Drawings;
using Jc.MicroDesigner.Management;
using Jc.MicroDesigner.Objects;

namespace Jc.MicroDesigner.ElementsLib
{
    /// <summary>
    /// Генератор синхроимпульсов
    /// </summary>
    [DrawingToolItem("Генератор импульсов","Генераторы")]
    public class ClockGenerator : CircuitElement, ISignalGenerator, IClockGenerator
    {
        int _StartTime = 0;
        int _TactTime = 16;
        int _ClockTime = 4;
        int _Shift = 0;
        sbyte _Signal = 1;

        public ClockGenerator(ObjectManager manager)
            : base(manager, "clock.xml") 
        {
            manager.Generators.Add(this);
        }

        #region IClockGenerator Members

        /// <summary>
        /// Время первого импульса
        /// </summary>
        public int StartTime
        {
            get
            {
                return _StartTime;
            }
            set
            {
                _StartTime = value;
            }
        }

        /// <summary>
        /// Такт в нс
        /// </summary>
        public int TactTime
        {
            get
            {
                return _TactTime;
            }
            set
            {
                _TactTime = value;
            }
        }

        /// <summary>
        /// Длительность импульса
        /// </summary>
        public int ClockTime
        {
            get
            {
                return _ClockTime;
            }
            set
            {
                _ClockTime = value;
            }
        }

        /// <summary>
        /// Генерируемый сигнал
        /// </summary>
        public sbyte Signal
        {
            get
            {
                return _Signal;
            }
            set
            {
                _Signal = value;
            }
        }

        /// <summary>
        /// Сдвиг первого такта
        /// </summary>
        public int Shift
        {
            get { return _Shift; }
            set { _Shift = value; }
        }
        #endregion

        #region ISignalGenerator Members

        public SignalContainer SignalsCollection
        {
            get { return null; }
        }

        public void GenerateSignal(int time, int tact)
        {
            int timex = tact * _Manager.TicPerTact + time;
            if (timex < _Shift)
                _PINCollection[0].Send(Convert.ToSByte(1 - Signal));
            else
            {
                timex = (timex - _Shift) % _TactTime;
                if ((timex >= _StartTime) && (timex < _ClockTime + _StartTime))
                    //Импульс 1
                    _PINCollection[0].Send(Signal);
                else
                    //Нулевой сигнал
                    _PINCollection[0].Send(Convert.ToSByte(1 - Signal));
            }
        }

        //Нередактируемый генератор
        public bool Editable
        {
            get { return false; }
        }

        #endregion

        public override void SaveAdditionals(Dictionary<ConfigSection, XmlNode> nodes)
        {
            XmlNode additionals_node = nodes[ConfigSection.Additionals];
            XmlDocument doc = additionals_node.OwnerDocument;
            Hashtable props = new Hashtable();
            props.Add("StartTime", StartTime);
            props.Add("TactTime", TactTime);
            props.Add("ClockTime", ClockTime);
            props.Add("Signal", Signal);
            props.Add("Shift", Shift);
            SchemeSerializer.SaveProps(additionals_node, props);
        }
    }
}